package com.woniu.user.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWTUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.woniu.common.ResponseData;
import com.woniu.common.dto.UserDTO;
import com.woniu.common.dto.UserRoleDTO;
import com.woniu.common.utils.messageUtil.RandomCode;
import com.woniu.common.utils.messageUtil.SentMessage;
import com.woniu.user.entity.*;
import com.woniu.user.service.*;
import com.woniu.user.mapper.UserMapper;
import com.woniu.common.ResponseEnum;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author hasee
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2025-01-05 13:53:36
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    public static final String WONIU = "woniu";
    @Autowired
    private UserService userService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleMenuService roleMenuService;
    @Autowired
    private RoleAuthService roleAuthService;
    @Autowired
    private TAuthService tAuthService;
    @Autowired
    private TMenusService tMenusService;
    @Autowired
    private WhiteListService whiteListService;

    @Override
    public ResponseData<?> phoneLogin(UserDTO userDTO) {
        /**
         *
         * array[menu对象]
         *
         *
         */


        //账号密码登录
        User user = lambdaQuery().eq(User::getAccountName, userDTO.getAccountName())
                .one();
        if (user != null) {
            String password = userDTO.getOldPassword();
            String newPassword = SecureUtil.md5(SecureUtil.md5(password) + "woniu");
            if (newPassword.equals(user.getPassword())) {
                //生成token
                HashMap map = new HashMap<>();
                map.put("user", user);
                String token = JWTUtil.createToken(map, WONIU.getBytes());
                //先查看redis有无该jwt，有的话给jwt续期
                String token2 = redisTemplate.opsForValue().get(user.getAccountName());
                if (token2 != null) {
                    redisTemplate.expire(user.getAccountName(), 72, TimeUnit.HOURS);
                } else {
                    redisTemplate.opsForValue().set(user.getAccountName(), token, 72, TimeUnit.HOURS);
                }
                user.setPassword(null);
                user.setFaceBase(null);
                return new ResponseData<>().ok(user);
            }
        }
        return new ResponseData<>().fail(ResponseEnum.LOGIN_ERROR);
    }

    @Override
    public ResponseData<?> getCode(String phoneNum) {
        String code = RandomCode.getRandomCode();
        redisTemplate.delete(phoneNum);
        redisTemplate.opsForValue().set(phoneNum, code);
        try {
            SentMessage.startSent(phoneNum, code);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return new ResponseData<>().ok(code);
    }

    @Override
    public ResponseData<?> register(UserDTO userDTO) {
        String accountName = userDTO.getAccountName();
        String code = userDTO.getCode();
        if (checkCode(accountName, code)) {
            User user = lambdaQuery().eq(User::getAccountName, accountName).one();
            if (user != null) {
                return new ResponseData<>().fail(ResponseEnum.REGISTER_ERROR);
            }
            //删除验证码
            redisTemplate.delete(accountName);
            User newUser = new User();
            newUser.setAccountName(userDTO.getAccountName());
            String newPassword = SecureUtil.md5(SecureUtil.md5("123456") + "woniu");
            newUser.setPassword(newPassword);
            save(newUser);
            user = lambdaQuery().eq(User::getAccountName, accountName).one();
            //生成token
            HashMap map = new HashMap<>();
            user.setPassword(null);
            user.setFaceBase(null);
            map.put("user", user);
            String token = JWTUtil.createToken(map, WONIU.getBytes());
            //先查看redis有无该jwt，有的话给jwt续期
            String token2 = redisTemplate.opsForValue().get(user.getAccountName());
            if (token2 != null) {
                redisTemplate.expire(user.getAccountName(), 72, TimeUnit.HOURS);
            } else {
                redisTemplate.opsForValue().set(user.getAccountName(), token, 72, TimeUnit.HOURS);
            }
            user.setPassword(null);
            user.setFaceBase(null);
            return new ResponseData<>().ok(user);
        }

        return new ResponseData<>().fail(ResponseEnum.CODE_ERROR);

    }

    @Override
    public ResponseData<?> codeLogin(UserDTO userDTO) {
        String accountName = userDTO.getAccountName();
        String code = userDTO.getCode();
        if (checkCode(accountName, code)) {
            User user = lambdaQuery().eq(User::getAccountName, accountName).one();
            if (user != null) {
                //删除验证码
                redisTemplate.delete(accountName);
                //生成token
                HashMap map = new HashMap<>();
                user.setPassword(null);
                user.setFaceBase(null);
                map.put("user", user);
                String token = JWTUtil.createToken(map, WONIU.getBytes());
                //先查看redis有无该jwt，有的话给jwt续期
                String token2 = redisTemplate.opsForValue().get(user.getAccountName());
                if (token2 != null) {
                    redisTemplate.expire(user.getAccountName(), 72, TimeUnit.HOURS);
                } else {
                    redisTemplate.opsForValue().set(user.getAccountName(), token, 72, TimeUnit.HOURS);
                }
                user.setPassword(null);
                user.setFaceBase(null);
                return new ResponseData<>().ok(user);
            }
            return new ResponseData<>().fail(ResponseEnum.NO_REGISTER);
        }
        return new ResponseData<>().fail(ResponseEnum.CODE_ERROR);
    }

    @Override
    public ResponseData<?> registerApp(UserDTO userDTO) {
        String accountName = userDTO.getAccountName();
        String code = userDTO.getCode();
        if (checkCode(accountName, code)) {
            User user = lambdaQuery().eq(User::getAccountName, accountName).one();
            if (user != null) {
                redisTemplate.delete(accountName);
                return new ResponseData<>().ok(user.getAccountName());
            }
            //删除验证码
            redisTemplate.delete(accountName);
            User newUser = new User();
            newUser.setAccountName(userDTO.getAccountName());
            String newPassword = SecureUtil.md5(SecureUtil.md5("123456") + "woniu");
            newUser.setPassword(newPassword);
            save(newUser);
            user = lambdaQuery().eq(User::getAccountName, accountName).one();
            //生成token
            HashMap map = new HashMap<>();
            user.setPassword(null);
            user.setFaceBase(null);
            map.put("user", user);
            String token = JWTUtil.createToken(map, WONIU.getBytes());
            //先查看redis有无该jwt，有的话给jwt续期
            String token2 = redisTemplate.opsForValue().get(user.getAccountName());
            if (token2 != null) {
                redisTemplate.expire(user.getAccountName(), 72, TimeUnit.HOURS);
            } else {
                redisTemplate.opsForValue().set(user.getAccountName(), token, 72, TimeUnit.HOURS);
            }
            user.setPassword(null);
            user.setFaceBase(null);
            return new ResponseData<>().ok(user);
        }

        return new ResponseData<>().fail(ResponseEnum.CODE_ERROR);
    }

    @Override
    public ResponseData<?> changePassword(UserDTO userDTO) {
        // 1. 参数校验
        if (StringUtils.isBlank(userDTO.getAccountName()) ||
                StringUtils.isBlank(userDTO.getOldPassword()) ||
                StringUtils.isBlank(userDTO.getPassword())) {
            return new ResponseData<>().fail(ResponseEnum.USER_NOT_FOUND);
        }

        // 2. 查询用户是否存在
        User user = userService.lambdaQuery()
                .eq(User::getAccountName, userDTO.getAccountName())
                .one();
        if (user == null) {
            return new ResponseData<>().fail(ResponseEnum.USER_NOT_FOUND);
        }

        // 3. 验证旧密码
        String oldPasswordMd5 = SecureUtil.md5(SecureUtil.md5(userDTO.getOldPassword()) + "woniu");
        if (!user.getPassword().equals(oldPasswordMd5)) {
            return new ResponseData<>().fail(ResponseEnum.INVALID_OLD_PASSWORD);
        }

        // 4. 加密新密码
        String newPasswordMd5 = SecureUtil.md5(SecureUtil.md5(userDTO.getPassword()) + "woniu");

        // 5. 更新密码
        boolean updated = userService.lambdaUpdate()
                .eq(User::getAccountName, userDTO.getAccountName())
                .setSql("password = '" + newPasswordMd5 + "'")  // 注意添加单引号
                .update();

        if (!updated) {
            return new ResponseData<>().fail(ResponseEnum.UPDATE_FAILED);
        }

        return new ResponseData<>().ok("密码修改成功");
    }

    @Override
    public ResponseData<?> init() {
        //先删除，再添加
        //初始化页面权限
        redisTemplate.delete("UserRole");
        List<UserRole> userRoleList = userRoleService.list();
        Iterator<UserRole> iterator = userRoleList.iterator();
        while (iterator.hasNext()) {
            UserRole userRole = iterator.next();
            Long accountId = userRole.getAccountId();
            Integer roleId = userRole.getRoleId();
            redisTemplate.opsForHash().put("UserRole", "账户ID--" + accountId.toString(), roleId.toString());
        }
        redisTemplate.delete("RoleMenu");
        List<RoleMenu> roleMenuList = roleMenuService.list();
        Iterator<RoleMenu> iterator1 = roleMenuList.iterator();
        while (iterator1.hasNext()) {
            RoleMenu roleMenu = iterator1.next();
            Integer roleId = roleMenu.getId();
            //redisTemplate.opsForHash().put("RoleMenu", roleId.toString(), JSON.toJSONString(roleMenu));
            redisTemplate.opsForHash().put("RoleMenu", "角色菜单表ID--" + roleId.toString(), JSON.toJSONString(roleMenu));
        }
        redisTemplate.delete("Menus");
        List<TMenus> menusList = tMenusService.list();
        Iterator<TMenus> iterator2 = menusList.iterator();
        while (iterator2.hasNext()) {
            TMenus tMenus = iterator2.next();
            Integer menuId = tMenus.getId();
            redisTemplate.opsForHash().put("Menus", "菜单ID--" + menuId.toString(), JSON.toJSONString(tMenus));
        }
        //初始化白名单
        redisTemplate.delete("WhiteList");
        List<WhiteList> whiteListList = whiteListService.list();
        Iterator<WhiteList> iterator3 = whiteListList.iterator();
        while (iterator3.hasNext()) {
            WhiteList whiteList = iterator3.next();
            redisTemplate.opsForHash().put("WhiteList", whiteList.getPath(), whiteList.getRouteType());
        }
        //初始化路径按钮权限
        redisTemplate.delete("RoleAuth");
        List<RoleAuth> roleAuthList = roleAuthService.list();
        Iterator<RoleAuth> iterator4 = roleAuthList.iterator();
        while (iterator4.hasNext()) {
            RoleAuth roleAuth = iterator4.next();
            redisTemplate.opsForHash().put("RoleAuth", "角色权限表ID--" + roleAuth.getId().toString(), JSON.toJSONString(roleAuth));
        }
        redisTemplate.delete("Auth");
        List<TAuth> tAuthList = tAuthService.list();
        Iterator<TAuth> iterator5 = tAuthList.iterator();
        while (iterator5.hasNext()) {
            TAuth tAuth = iterator5.next();
            redisTemplate.opsForHash().put("Auth", "权限ID--" + tAuth.getId().toString(), JSON.toJSONString(tAuth));
        }
        //初始化用户表
        redisTemplate.delete("User");
        List<User> userList = userService.list();
        Iterator<User> iterator6 = userList.iterator();
        while (iterator6.hasNext()) {
            User user = iterator6.next();
            redisTemplate.opsForHash().put("User", user.getAccountName(), user.getId().toString());
        }


        return new ResponseData<>().ok("系统初始化完成");
    }

    @Override
    public ResponseData<?> checkUser(UserDTO userDTO) {
        try {
            // 参数校验
            if (userDTO == null) {
                return new ResponseData<>().fail(ResponseEnum.NO_STRING);
            }

            // 查询用户是否存在
            User user = userService.lambdaQuery()
                    .eq(User::getAccountName, userDTO.getAccountName())
                    .one();

            if (user != null) {
                return new ResponseData<>().fail(ResponseEnum.REGISTER_ERROR);
            }

            return new ResponseData<>().ok("用户不存在，可以注册");

        } catch (Exception e) {
            log.error("检查用户是否存在时发生错误: ", e);
            return new ResponseData<>().fail(ResponseEnum.SYS_BUSY);
        }
    }

    @Override
    public ResponseData<?> queryAllUserRole() {
        return new ResponseData<>().ok(userMapper.queryAllUserAndRole());
    }

    @Override
    public ResponseData<?> updateUserRole(UserRoleDTO userDTO) {
        Long userId = userDTO.getId();
        //1.管理员 2.财务 3.门卫 4.物业 5.业主
        Integer roleId = userDTO.getRoleId();
        UserRole one = userRoleService.lambdaQuery().eq(UserRole::getAccountId, userId).one();
        if (one != null) {
            one.setRoleId(roleId);
            if (roleId.equals(1)){
                one.setRole("管理员");
            }
            if (roleId.equals(2)){
                one.setRole("财务");
            }
            if (roleId.equals(3)){
                one.setRole("门卫");
            }
            if (roleId.equals(4)){
                one.setRole("物业");
            }
            if (roleId.equals(5)){
                one.setRole("业主");
            }
            userRoleService.updateById(one);
            init();
            return new ResponseData<>().ok();
        }else {
            UserRole userRole = new UserRole();
            userRole.setAccountId(userId);
            userRole.setRoleId(roleId);
            if (roleId.equals(1)){
                userRole.setRole("管理员");
            }
            if (roleId.equals(2)){
                userRole.setRole("财务");
            }
            if (roleId.equals(3)){
                userRole.setRole("门卫");
            }
            if (roleId.equals(4)){
                userRole.setRole("物业");
            }
            if (roleId.equals(5)){
                userRole.setRole("业主");
            }
            userRoleService.save(userRole);
            init();
            return new ResponseData<>().ok();
        }
    }

    public boolean checkCode(String phoneNum, String code) {
        String msg = redisTemplate.opsForValue().get(phoneNum);
        if (msg.equals(code)) {
            return true;
        } else {
            return false;
        }
    }


}




